package com.freewater.javabase.demo.network.tcp;

import com.google.common.collect.Sets;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;
import java.util.Set;

// 向dict.org发送翻译请求
public class DictClient {

    private static final String DICT_SERVER_HOST = "dict.org";

    private static final int DICT_SERVER_PORT = 2628;

    private static final int TIMEOUT = 15 * 1000;

    public static void main(String[] args) {
        try (Socket socket = new Socket(DICT_SERVER_HOST, DICT_SERVER_PORT)) {
            socket.setSoTimeout(TIMEOUT);
            final OutputStream outputStream = socket.getOutputStream();
            final InputStream inputStream = socket.getInputStream();
            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
            final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            final Set<String> dicDBs = showDB(writer, reader);
            System.out.println("choose dict db: ");
            final Scanner scanner = new Scanner(System.in);
            final String nextLine = scanner.nextLine();
            if (!dicDBs.contains(nextLine)) {
                System.out.println("please input valid dict db");
                System.exit(0);
            }
            final String useDB = nextLine.trim();
            while (true) {
                System.out.println("please input word to define:");
                final String userInput = scanner.nextLine();
                if (userInput != null && userInput.trim().equalsIgnoreCase("quit")) {
                    writer.write("quit\r\n");
                    writer.flush();
                    break;
                } else {
                    String commandLine = "DEFINE " + useDB + " " + userInput.trim();
                    define(writer, reader, commandLine);
                }
            }
        } catch (IOException e) {
            System.out.println("exit with exception: " + e.getMessage());
        }
    }

    public static Set<String> showDB(BufferedWriter writer, BufferedReader reader) throws IOException {
        final Set<String> dicDBs = Sets.newHashSet();
        writer.write("SHOW DB\r\n");
        writer.flush();
        System.out.println("DB\tDescription\tVersion");
        for (String line = reader.readLine(); line != null; line = reader.readLine()) {
            if (line.startsWith("250 ")) {
                return dicDBs;
            } else if (line.startsWith("\\d\\d\\d .*")) {
                continue;
            } else if (line.trim().equals(".")) {
                continue;
            }
            if (line.startsWith("fd-")) {
                final int index = line.indexOf(" ");
                dicDBs.add(line.substring(0, index));
            }
            System.out.println(line);
        }
        return dicDBs;
    }

    private static void define(BufferedWriter writer, BufferedReader reader, String defineCommand) throws IOException {
        writer.write(defineCommand + "\r\n");
        writer.flush();
        for (String line = reader.readLine(); line != null; line = reader.readLine()) {
            if (line.startsWith("250 ")) {
                return;
            } else if (line.startsWith("552 ")) { // 无匹配
                System.out.println("No definition found for \"" + defineCommand + "\"");
                return;
            } else if (line.startsWith("\\d\\d\\d .*")) {
                continue;
            } else if (line.trim().equals(".")) {
                continue;
            }
            System.out.println(line);
        }
    }
}
